import React from 'react';
import { Form as Form_ } from 'antd';
import { FormProps, ValidationRule, FormItemProps, FormComponentProps } from 'antd/es/form';
import { WrappedFormUtils } from 'antd/es/form/Form';
import { Spin } from './feedback';
import { Input } from './input';
import { space } from '../../../tool/reg_exp';
import style from './style.module.less';

interface IFormProps extends FormProps {
  loading?: boolean;
}

/**
 * 表单
 * @param  {Boolean}   options.loading [description]
 * @param  {...[type]} options.props   [description]
 * @return {[type]}                    [description]
 */
export const Form: React.SFC<IFormProps> = ({ loading = false, ...props }) => (
  <Spin spinning={loading}>
    <Form_ className={style.form} {...props} />
  </Spin>
);

interface IValueProps {
  name: string; // 字段名
  rules?: string | ValidationRule[]; // 验证规则
  validator?: (value: any) => string | undefined; // 额外验证器
  initialValue?: string | number; // 默认值
  label?: string; // 标题
  itemProps?: FormItemProps;
  fill?: boolean; // 占满一行
}

/**
 * 创建字段组件
 * @param  {[type]} getFieldDecorator: WrappedFormUtils['getFieldDecorator']): React.SFC < IValueProps > [description]
 * @return {[type]}                    [description]
 */
export const createValueItem = (getFieldDecorator: WrappedFormUtils['getFieldDecorator']): React.SFC<IValueProps> => ({
  name,
  rules = [],
  validator,
  initialValue,
  children,
  label,
  itemProps,
  fill,
  ...props
}) => {
  // 自动加入必填提示
  if (typeof rules === 'string') {
    rules = [
      {
        required: true,
        message: rules,
      },
    ];
  }
  // 不可提交空格
  rules.push({
    validator: (rule, value, callback) => {
      let msg;
      if (value) {
        if (typeof value === 'string' && !space.test(value)) msg = '不可提交空格';
      }
      if (!msg && validator) {
        msg = validator(value);
      }
      callback(msg);
    },
  });

  // 栅格
  const itemProps_ = {
    style: {
      width: '50%',
    },
    labelCol: {
      span: 8,
    },
    wrapperCol: {
      span: 14,
    },
  };

  if (fill) {
    itemProps_.style.width = '100%';
    itemProps_.labelCol.span = 4;
    itemProps_.wrapperCol.span = 19;
  }

  if (!label) {
    itemProps_.labelCol.span = 0;
    itemProps_.wrapperCol.span = 24;
  }

  return (
    <Form_.Item label={label} className={style.formItem} {...itemProps_} {...itemProps}>
      {getFieldDecorator(name, {
        rules,
        initialValue,
        validateFirst: true,
      })(children || <Input {...props} />)}
    </Form_.Item>
  );
};

interface IFormBoxProps extends FormComponentProps {
  onSubmit?: (value: any) => void;
  onForm?: (form: WrappedFormUtils) => void;
  children: (ValueItem: React.SFC<IValueProps>) => JSX.Element;
}

class FormBox_ extends React.Component<IFormBoxProps> {
  state = {
    loading: false,
  };

  ValueItem = createValueItem(this.props.form.getFieldDecorator);

  componentDidMount() {
    const { onForm, form } = this.props;
    onForm && onForm(form);
  }

  submit = (e: React.FormEvent) => {
    e.preventDefault();
    const { form, onSubmit } = this.props;
    onSubmit &&
      form.validateFieldsAndScroll(async (error, value) => {
        if (error) return;
        this.setState({
          loading: true,
        });
        await onSubmit(value);
        this.setState({
          loading: false,
        });
      });
  };

  render() {
    const { children } = this.props;
    return (
      <Form onSubmit={this.submit} {...this.state}>
        {children && children(this.ValueItem)}
      </Form>
    );
  }
}

/**
 * 表单模块
 */
export const FormBox = Form_.create()(FormBox_);
